#include "CrypUtil.h"
#include "depends/md5.h"
#include "depends/uz.h"
#include "depends/base64.h"

using namespace x2lib;

char* CrypUtil::Md5(const uint8_t* pData, int nData, char szMd5Val[/*64*/])
{
	MD5_CTX mdContext;
	MD5Init(&mdContext);
	MD5Update(&mdContext, (unsigned char*)pData, nData);
	MD5Final(&mdContext);

	szMd5Val[0] = 0;
	for (int i = 0; i < sizeof(mdContext.digest); i++)
	{
		sprintf(szMd5Val, "%s%02x", szMd5Val, mdContext.digest[i]);
	}

	return szMd5Val;
}

void* CrypUtil::Base64(void* pData, int nData, void* pDataout, int* pnDataout, bool isEncrypt)
{
	if (isEncrypt) return (void*)base64_encode(pData, nData, (unsigned char*)pDataout, pnDataout);
	else return base64_decode((const char*)pData, pDataout, pnDataout);
}

void* CrypUtil::Encrypt(void* out, void* in, DWORD size, uint8_t key)
{
	for (DWORD i = 0; i < size; i++)
		((BYTE*)out)[i] = ((BYTE*)in)[i] ^ key;

	return out;
}

void* CrypUtil::Decrypt(void* out, void* in, DWORD size, uint8_t key)
{
	for (DWORD i = 0; i < size; i++)
		((BYTE*)out)[i] = ((BYTE*)in)[i] ^ key;

	return out;
}

void* CrypUtil::Encrypt1(void* pIn, void* pOut, DWORD nLen, uint8_t uKey)
{
	memcpy(pOut, pIn, nLen);
	int i = nLen - 1;
	((char*)pOut)[i] ^= uKey;
	for (; i > 0; i--)
	{
		((char*)pOut)[i - 1] ^= ((char*)pOut)[i];
	}

	return pOut;
}

void* CrypUtil::Decrypt1(void* pIn, void* pOut, DWORD nLen, uint8_t uKey)
{
	memcpy(pOut, pIn, nLen);
	for (DWORD i = 0; i < nLen - 1; i++)
	{
		((char*)pOut)[i] ^= ((char*)pOut)[i + 1];
	}
	((char*)pOut)[nLen - 1] ^= uKey;

	return pOut;
}

void* CrypUtil::Encrypt2(void* pIn, void* pOut, uint32_t nLen, const char* szPwd)
{
	int nKey = strlen(szPwd);
	for (uint32_t i = 0; i < nLen; i++)
		*((uint8_t*)pOut + i) = *((uint8_t*)pIn + i) ^ szPwd[i % nKey];

	return pOut;
}

void* CrypUtil::Decrypt2(void* pIn, void* pOut, uint32_t nLen, const char* szPwd)
{
	return Encrypt2(pIn, pOut, nLen, szPwd);
}
